#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "StdFile.h"


char* LoadFromFile(const char* FilePath)
{
    FILE* file = fopen(FilePath,"r");//打开文件夹
    if(file == NULL)
    {
        printf("File %s open fail!\n", FilePath);
        return NULL;
    }
    fseek(file, 0, SEEK_END);//光标定位到文件尾
    size_t size = ftell(file);//统计从文件开头到光标处的字符数量

    char* content = (char*)malloc(size + 1);//创建
    fseek(file, 0, SEEK_SET);//光标定位到文件头
    fread(content, size, 1, file);//读取文件内容保存到content
    fclose(file);//关闭文件
    return content;
}

//文件是否存在
int IsFileExist(const char* FilePath)
{
    FILE* file = fopen(FilePath, "r");
    if(file == NULL)//打不开文件，即文件不存在
        return false;
    else
    {
        fclose(file);//能打开文件，即文件不存在，判断后关闭文件
        return true;
    }
}

//删除index处字符
void RemoveCharIndex(char* arr, int index)
{
    if(index < 0 || index >= strlen(arr))
    {
        printf("RemoveCharIndex invalid parameter!\n");
        return;
    }
    for(int i = index; i < strlen(arr); ++i)
    {
        arr[i] = arr[i+1];//向前移一位覆盖掉要移除的字符
    }
}


//删除特定字符
void RemoveChar(char* arr, char element)
{
    int len = strlen(arr);
    for(int i = 0; i < len; ++i)
    {
        if(arr[i] == element)
        {
            RemoveCharIndex(arr, i);
            --i;//每移除一个指定字符，后面字符的往前移动一位覆盖，下标-1
        }
    }
}

//按行读取文件内容
DList* GetLineFromFile(const char* FilePath)
{
    FILE* file = fopen(FilePath,"r");//以只读方式打开FilePath路径下的文件
    if(file == NULL)
    {
        printf("File %s open fail!\n", FilePath);
        return NULL;
    }
    DList* list = (DList*)malloc(sizeof(DList));//创建链表保存文件内容
    DList_Init(list);
    
    char ContentTemp[100] = {0};
    while(fgets(ContentTemp, 100, file) != NULL)//每读取一行文件内容，暂存到ContentTemp
    {
        char* Line = (char*)malloc(strlen(ContentTemp) + 1);
        strcpy(Line, ContentTemp);//将一行数据帮存到Line，并追加‘\0’
        RemoveChar(Line, '\n');//清除fgets函数读取文件一行末尾的‘\n’
        DList_InsertTail(list, Line);//每读取一行创建一个节点保存到链表
    }
    fclose(file);
    return list;
}

//写，不存在创建，存在删空
void WriteToFile(const char* FilePath, void* ptr, size_t size)
{
    FILE* file = fopen(FilePath, "w");//以只写方式打开FilePath路径下的文件
    if(file == NULL)
    {
        printf("WritetoFile open file error!\n");
        return;
    }
    if(fwrite(ptr, size, 1, file) <= 0)//将缓冲区ptr往file文件读取size个字节字符，仅读1次
        printf("WritetoFile error!\n");
    fclose(file);
}

//写一行
void WriteLineToFile(const char* FilePath, DList* list)
{
    FILE* file = fopen(FilePath, "w");//以只写方式打开FilePath路径下的文件
    if(file == NULL)
    {
        printf("WritetoFile open file error!\n");
        return;
    }
    DNode* cur = list->head;//创建遍历节点
    while(cur != NULL)
    {
        fputs(cur->data, file);//将每一个节点的内容去掉‘\0’输入到文件
        cur = cur->next;
    }
    fclose(file);
}

//追加写
void AppendToFile(const char* FilePath, void* ptr, size_t size)
{
    FILE* file = fopen(FilePath, "a");//以追加写方式打开FilePath路径下的文件,不存在创建
    if(file == NULL)
    {
        printf("WritetoFile open file error!\n");
        return;
    }
    fwrite(ptr, size, 1, file);//将缓冲区ptr往file文件读取size个字节字符，仅读1次
    fclose(file);
}

//拷贝文件
void CopyFile(const char* SourcePath, const char* TargetPath)
{
    if(IsFileExist(SourcePath) == false)//文件不存在
    {
        printf("The SoureFile is not exist or has no read permission!\n");
        return;
    }
    char* fileContent = LoadFromFile(SourcePath);
    if(IsFileExist(TargetPath) == true)//目标文件存在
    {
        //strtok//字符串切割函数,原字符串在切割处变成“\0”,需转存
        char Target[100] = {0};
        strcpy(Target, TargetPath);//将目标文件路径暂存到Target
        char* fileName = strtok(Target, ".");//获取路径"."前字符串
        char* backName = strtok(NULL, ".");//获取路径"."后字符串

        char newPath[100] = {0};
        strcpy(newPath, fileName);//将路径"."前字符串存入newPath
        strcat(newPath, "_new.");//新文件路径追加"_new."
        strcat(newPath,backName);//将旧路径"."后字符串追加（文件后缀）
        if(IsFileExist(newPath) == true)//若文件拷贝时，重命名的路径存在，继续递归
        {
            CopyFile(SourcePath, newPath);
            return;
        }   
        WriteToFile(newPath, fileContent, strlen(fileContent));//将旧文件内容拷贝到新文件
        free(fileContent);
        return;
    }
    WriteToFile(TargetPath, fileContent, strlen(fileContent));//目标文件不存在，创建，并拷贝
    free(fileContent);
}



